/**
 * 原生弹窗界面类，使用plus.nativeObj绘制
 * @version 2021-10-20 zzc
 * @updated 2025-04-17 转换为TypeScript
 */
class Dialog {
  private maskLayer: any // 遮罩层视图
  private popupEle: any // 弹窗主体视图

  constructor() {
    this.maskLayer = {} as any
    this.popupEle = {} as any
  }

  /**
   * 显示弹窗
   * @param {Object} params - 配置参数对象
   * @param {string} [params.title='提示'] - 标题文字
   * @param {string} params.content - 内容文本
   * @param {boolean} [params.showCancel=true] - 是否显示取消按钮
   * @param {boolean} [params.showSecond=true] - 是否显示确认按钮
   * @param {string} [params.cancelText='取消'] - 取消按钮文字
   * @param {string} [params.confirmText='确定'] - 确定按钮文字
   * @param {Function} [params.confirm] - 确定按钮回调函数
   * @param {Function} [params.cancel] - 取消按钮回调函数
   * @param {string} [params.icon] - 顶部图标地址
   * @param {'left'|'center'} [params.titleAlign='center'] - 标题对齐方式
   * @param {'left'|'center'} [params.contentAlign='left'] - 内容对齐方式
   * @param {boolean} [params.noClose=false] - 点击按钮后是否不关闭弹窗
   */
  show(params: {
    title?: string
    content: string
    showCancel?: boolean
    showSecond?: boolean
    cancelText?: string
    confirmText?: string
    confirm?: () => void
    cancel?: () => void
    icon?: string
    titleAlign?: 'left' | 'center'
    contentAlign?: 'left' | 'center'
    noClose?: boolean
  }): void {
    this.drawView(params)
    this.maskLayer.show()
    this.popupEle.show()
  }

  /**
   * 隐藏弹窗
   */
  hide(): void {
    if (Object.keys(this.maskLayer).length !== 0 && Object.keys(this.popupEle).length !== 0) {
      this.maskLayer.hide()
      this.popupEle.hide()
    }
  }

  /**
   * 绘制确认对话框UI
   * @param {Object} params - 配置参数对象
   */
  private drawView(params: {
    title?: string
    content: string
    showCancel?: boolean
    showSecond?: boolean
    cancelText?: string
    confirmText?: string
    confirm?: () => void
    cancel?: () => void
    icon?: string
    titleAlign?: 'left' | 'center'
    contentAlign?: 'left' | 'center'
    noClose?: boolean
  }): void {
    // 解构参数并设置默认值
    const {
      confirmText = '确定',
      cancelText = '取消',
      titleAlign = 'center',
      contentAlign = 'left',
      title = '提示',
      content,
      showCancel = true,
      showSecond = true,
      confirm,
      cancel,
      icon,
      noClose = false,
    } = params

    // 获取屏幕尺寸
    const screenWidth: number = plus.screen.resolutionWidth
    const screenHeight: number = plus.screen.resolutionHeight

    // 计算弹窗尺寸
    const popWidth: number = screenWidth * 0.8
    let popHeight: number = showSecond ? 80 + 20 + 20 + 90 + 20 : 80 + 70 + 10 + 10

    // 正文距离顶部
    let contentTop: number = 132

    // 弹窗容器的Padding
    const viewPadding: number = 20

    // 弹窗容器的宽度
    const viewWidth: number = parseInt((popWidth - viewPadding * 2).toString())

    // 更新描述文字
    const description: Array<{ type: string; content: string }> = this.drawText(content, viewWidth)

    const textHeight: number = 18
    const popContent: any[] = []

    // 确认按钮文本配置
    const confirmTextConfig = {
      tag: 'font',
      id: 'confirmText',
      text: confirmText,
      textStyles: {
        size: '14px',
        color: '#FFF',
        lineSpacing: '0%',
      },
    }

    // 如果有图标则添加图标
    if (icon) {
      popContent.unshift({
        src: icon,
        id: 'logo',
        tag: 'img',
        position: {
          top: '0px',
          left: (popWidth - 124) / 2 + 'px',
          width: '124px',
          height: '80px',
        },
      })
    } else {
      popHeight -= 30
      contentTop = 105
    }

    // 如果有标题则添加标题
    if (title) {
      popContent.push({
        tag: 'font',
        id: 'title',
        text: title,
        textStyles: {
          size: '18px',
          color: '#333',
          weight: 'bold',
          whiteSpace: 'normal',
        },
        position: {
          top: icon ? '90px' : '60px',
          left: titleAlign === 'center' ? `${viewPadding}px` : '-25px',
          width: viewWidth + 'px',
          height: '30px',
        },
      })
    } else {
      contentTop = 90
    }

    // 添加内容文本
    description.forEach((item, index) => {
      if (index > 0) {
        popHeight += textHeight
        contentTop += textHeight
      }
      popContent.push({
        tag: 'font',
        id: 'content' + (index + 1),
        text: item.content,
        textStyles: {
          size: '14px',
          color: '#666',
          lineSpacing: '50%',
          align: content.length < 16 ? 'center' : contentAlign,
        },
        position: {
          top: contentTop + 'px',
          left: viewPadding + 'px',
          width: viewWidth + 'px',
          height: textHeight + 'px',
        },
      })
      if (item.type === 'break') {
        contentTop += 10
        popHeight += 10
      }
    })

    // 处理按钮区域
    if (!showCancel) {
      if (showSecond) {
        // 只显示确认按钮
        popContent.push({
          tag: 'rect',
          rectStyles: {
            radius: '6px',
            color: '#409EFF',
          },
          position: {
            bottom: viewPadding + 'px',
            left: viewPadding + 'px',
            width: viewWidth + 'px',
            height: '40px',
          },
        })
        popContent.push({
          ...confirmTextConfig,
          position: {
            bottom: viewPadding + 'px',
            left: viewPadding + 'px',
            width: viewWidth + 'px',
            height: '40px',
          },
        })
      }
    } else {
      // 显示取消和确认按钮
      popContent.push({
        tag: 'rect',
        id: 'cancelBox',
        rectStyles: {
          radius: '5px',
          borderColor: '#eeeeee',
          color: '#f0f0f0',
          borderWidth: '1px',
        },
        position: {
          bottom: viewPadding + 'px',
          left: viewPadding + 'px',
          width: (viewWidth - viewPadding) / 2 + 'px',
          height: '40px',
        },
      })
      popContent.push({
        tag: 'rect',
        id: 'confirmBox',
        rectStyles: {
          radius: '5px',
          color: '#409EFF',
        },
        position: {
          bottom: viewPadding + 'px',
          left: (viewWidth - viewPadding) / 2 + viewPadding * 2 + 'px',
          width: (viewWidth - viewPadding) / 2 + 'px',
          height: '40px',
        },
      })
      popContent.push({
        tag: 'font',
        id: 'cancelText',
        text: cancelText,
        textStyles: {
          size: '14px',
          color: '#666',
          lineSpacing: '0%',
          whiteSpace: 'normal',
        },
        position: {
          bottom: viewPadding + 'px',
          left: viewPadding + 'px',
          width: (viewWidth - viewPadding) / 2 + 'px',
          height: '40px',
        },
      })
      popContent.push({
        ...confirmTextConfig,
        position: {
          bottom: viewPadding + 'px',
          left: (viewWidth - viewPadding) / 2 + viewPadding * 2 + 'px',
          width: (viewWidth - viewPadding) / 2 + 'px',
          height: '40px',
        },
      })
    }

    // 创建遮罩层
    this.maskLayer = new plus.nativeObj.View('maskLayer', {
      top: '0px',
      left: '0px',
      height: '100%',
      width: '100%',
      backgroundColor: 'rgba(0,0,0,0.5)',
    })

    // 创建弹窗主体
    this.popupEle = new plus.nativeObj.View('popupEle', {
      //   tag: 'rect',
      top: (screenHeight - popHeight) / 2 + 'px',
      left: '10%',
      height: popHeight + 'px',
      width: '80%',
    })

    // 绘制白色背景
    this.popupEle.drawRect(
      {
        color: '#FFFFFF',
        radius: '8px',
      },
      {
        top: '40px',
        height: popHeight - 40 + 'px',
      },
    )

    // 绘制所有内容
    this.popupEle.draw(popContent)

    // 添加点击事件处理
    this.popupEle.addEventListener('click', (e: any) => {
      const maxTop: number = popHeight - viewPadding
      const maxLeft: number = popWidth - viewPadding
      const buttonWidth: number = (viewWidth - viewPadding) / 2

      if (e.clientY > maxTop - 40 && e.clientY < maxTop) {
        if (!showCancel) {
          if (e.clientX > viewPadding && e.clientX < maxLeft) {
            // 点击确认按钮
            confirm && confirm()
            if (!noClose) {
              this.hide()
            }
          }
        } else {
          // 点击取消按钮
          if (e.clientX > viewPadding && e.clientX < maxLeft - buttonWidth - viewPadding) {
            cancel && cancel()
            this.hide()
          }
          // 点击确认按钮
          else if (e.clientX > maxLeft - buttonWidth && e.clientX < maxLeft) {
            confirm && confirm()
            this.hide()
          }
        }
      }
    })
  }

  /**
   * 文本换行处理
   * @param {string} text - 需要处理的文本内容
   * @param {number} maxWidth - 最大宽度限制
   * @returns {Array<{type: string; content: string}>} 处理后的文本数组
   */
  private drawText(text: string, maxWidth: number): Array<{ type: string; content: string }> {
    const textArr: string[] = text.split('')
    const len: number = textArr.length
    let previousNode: number = 0 // 上个节点位置
    let nodeWidth: number = 0 // 当前行宽度
    const rowText: Array<{ type: string; content: string }> = [] // 结果数组
    let letterWidth: number = 0 // 字母宽度计数

    // 字符宽度定义
    const chineseWidth: number = 14 // 中文字符宽度
    const otherWidth: number = 7 // 其他字符宽度

    for (let i = 0; i < len; i++) {
      // 处理中文字符
      if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) {
        if (letterWidth > 0) {
          if (nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth) {
            rowText.push({
              type: 'text',
              content: text.substring(previousNode, i),
            })
            previousNode = i
            nodeWidth = chineseWidth
            letterWidth = 0
          } else {
            nodeWidth += chineseWidth + letterWidth * otherWidth
            letterWidth = 0
          }
        } else {
          if (nodeWidth + chineseWidth > maxWidth) {
            rowText.push({
              type: 'text',
              content: text.substring(previousNode, i),
            })
            previousNode = i
            nodeWidth = chineseWidth
          } else {
            nodeWidth += chineseWidth
          }
        }
      }
      // 处理其他字符
      else {
        // 处理换行符
        if (/\n/g.test(textArr[i])) {
          rowText.push({
            type: 'break',
            content: text.substring(previousNode, i),
          })
          previousNode = i + 1
          nodeWidth = 0
          letterWidth = 0
        }
        // 处理转义换行符
        else if (textArr[i] === '\\' && textArr[i + 1] === 'n') {
          rowText.push({
            type: 'break',
            content: text.substring(previousNode, i),
          })
          previousNode = i + 2
          nodeWidth = 0
          letterWidth = 0
        }
        // 处理字母数字
        else if (/[a-zA-Z0-9]/g.test(textArr[i])) {
          letterWidth += 1
          if (nodeWidth + letterWidth * otherWidth > maxWidth) {
            rowText.push({
              type: 'text',
              content: text.substring(previousNode, i + 1 - letterWidth),
            })
            previousNode = i + 1 - letterWidth
            nodeWidth = letterWidth * otherWidth
            letterWidth = 0
          }
        }
        // 处理其他字符
        else {
          if (nodeWidth + otherWidth > maxWidth) {
            rowText.push({
              type: 'text',
              content: text.substring(previousNode, i),
            })
            previousNode = i
            nodeWidth = otherWidth
          } else {
            nodeWidth += otherWidth
          }
        }
      }
    }

    // 添加剩余文本
    if (previousNode < len) {
      rowText.push({
        type: 'text',
        content: text.substring(previousNode, len),
      })
    }

    return rowText
  }
}

// 导出单例实例
export default new Dialog()
